<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        //1.99乘法表
        // 思路
        // (1)首先需要一个空的字符变量装内容
        // (2)双重循环 外层控制总行数 内层控制总列数
        // (3)9次循环 列始终少于行 所以 j < = i;
        // (4)注意换行与拼写字符串顺序
        // var str = ''
        // for(var i = 1; i <= 9; i++) {
        //     for(var j = 1; j <= i; j++) {
        //         str += j + '×' + i + '=' + i * j
        //         str += '\t'
        //     }
        //      str +=  '\n'
        // }
        // console.log(str);

        //2. 弹出一一个输入框 问你爱我吗？如果输入我爱你 就提示结束 否则 一直询问
        // 思路
        // (1)一直询问（陷入死循环）则用while循环不添加递增(不加操作表达式的while会陷入死循环 机子不好不要随便用)
        // (2)注意需要保存用户每次输入的结果(不保存 while无法判断正确答案)
        //   var love =prompt('你爱我吗？')
        //   while(love !== '我爱你') {
        //       love = prompt('你爱我吗？')
        //   }
        //   alert('我也爱你')

        //3.简易atm机
        // 里面存有100 块钱
        // 如果存钱 就用输入的钱数加上先村的钱数 之后弹出显示余额提示框
        // 如果取钱 就减去 取的钱数 之后弹出显示余额提示框
        // 如果显示余额 就输出余额
        // 如果退出弹出退出信息框即可
        // 思路
        // (1)固定选项用switch语句
        // (2)声明初始金额变量保存
        // (3)需要在用户未退出atm机前保持页面初始化 所以需要循环
        // (4)default执行最终退出语句
        // (5)做的不好总觉得应该改进
        //  var chusi = 100;
        //  for(var atm = 1; atm <= 4; atm++) {
        //   atm = prompt('请输入您要做的操作序号：'+ '\n' + '1:存钱' + '\n' + '2:取现' + '\n' + '3:余额' + '\n' + '4:退出')
        //      switch(atm) {
        //          case '1':
        //     cunchu = prompt('请输入存入金额')
        //     chusi = chusi + parseFloat(cunchu)
        //         alert('您的余额为：'+ chusi)
        //           break
        //           case '2':
        //     quxian = prompt('请输入您要取的金额')
        //     chusi= chusi - quxian
        //         alert('您的余额为：' + chusi)
        //           break
        //           case '3' :
        //         alert('您的余额为：' + chusi)
        //           break
        //           default :
        //         alert('正在退出')
        //      }
        //  }


        // 4.写一个函数，用户输入任意两个数的任意算术运算（简单的计算器小功能）并能弹出运算后的结果
        // 思路
        // (1)用函数封装好算法
        // (2)实参接收的是数组 所以需要下标的方式 呈现不同算法结果
        // function getArr(arr){
        //   var num1 = prompt('请输入第一个数')
        //   var num2 = prompt('请输入第二个数')
        //   return [parseFloat(num1) + parseFloat(num2), +num1 - num2,num1 * num2,num1 / num2]
        // }
        // var re =  getArr()
        // alert('加法：'+ re[0] +'\n' + '减法:' + re[1] + '\n'+ '乘法:' + re[2] + '\n' + '除法:'+ re[3] )

        // 5.写一个函数，用户输入任意两个数的最大值 并能弹出运算后的结果
        // 思路
        // (1)函数封装 三元运算即可
        // (2)这里只是觉得三元很有意思 但想用明白应该不是我一个菜鸟所能想明白的
        // function getMax(num1,num2) {
        //       return num1 > num2 ? num1 : num2
        // }
        // getMax(num1 = prompt('请输入第一个数'))
        // getMax(num2 = prompt('请输入第二个数'))
        // alert(getMax(num1,num2))

        // 6.利用函数求任意一个数组中的最大值[5,2,99,101,67,77]
        // 思路
        // (1)遍历数组
        // (2)下标0存放max变量
        // (3)让数组剩余所有元素与之比较 如果arr[i] > max 则max = arr[i]
        // (4)return返回值
        //   function getMax(arr) {
        //     var max = arr[0]
        //     for(var i = 1; i < arr.length;i++) {
        //       if(arr[i] > max ) {
        //         max = arr[i]
        //       }
        //     }
        //     return max
        //   }
        //  var re = getMax([5,2,99,101,67,77])
        //  console.log(re);

        // 7.写一个函数，用户输入一个数判断是否是素数 并反弹出回值（又叫质数 只能被1和自身整除的数）
        //  思路
        // (1)只能被1和自身整除  1/1=1  也就是说0和1可以先排除掉
        // (2)然后反向推导 通过遍历num  在2 < num这个范围内能被取余为0的 则就不是质数 反之就是质数？
        // (3)因为质数只能被1和自身整除 for循环条件执行前写的很清楚把1和自身排除掉了i =2 i<num 不包括num就是不包括自身  如果能被取余 就不是质数
        // (4)反之 所有剩下不能被取余的 都是循环执行条件之外的 也就是 是质数的 所以要把是质数的return返回式写在循环外面
        // (5)绕的原因 是我太笨了理解的不好 感觉这题挺考验小白的
        //     function getPrime(num) {
        //         if(num == 0 || num == 1) {
        //           return num + '非质数'
        //         }
        //         for(var i = 2; i < num; i++) {
        //           if(num % i == 0) {
        //             return num + '非质数'
        //           }
        //         }
        //         return num + '是质数'
        //     }
        //  alert(getPrime(Number = prompt('请输入数值')))

        // 8.利用函数封装方式 翻转任意一个数组 // ['pink','blue','purple','black']
        //  思路
        // (1)翻转需要一组新数组存放元素
        // (2)翻转旧数组 从下标尾开始遍历 每轮递减
        // (3)新数组按length动态检测数组长度特性正向 接收 旧数组传递的数据
        // function get(arr) {
        //     var newArr = []
        //     if (arr instanceof Array) {
        //         for (var i = arr.length - 1; i >= 0; i--) {
        //             newArr[newArr.length] = arr[i]
        //         }
        //         return newArr
        //     } else {
        //         return 'error 不是一个数组格式'
        //     }
        // }
        // console.log(get(['pink', 'blue', 'purple', 'black']));
        // console.log(get('pink', 'blue', 'purple', 'black'));//这里不符合if判断条件 则返回else 不是一个数组

        // 9.利用函数封装冒泡排序 从大到小排列[1,2,3,4,5,6,7,8,9,10,11,12,14,15,18,23,13,12,45,6,778,45,345]
        // 思路
        // (1)双层循环 外层控制总趟数 内层控制每趟元素交换的总次数
        // (2)内层交换时 交换一次其实可以完成两个变量的互换 所以 条件表达式：在总个数的基础上在额外减少一次 j < arr.length - i -1
        // (3)如果内层循环元素 j < j+1 则交换变量
        // (4)交换变量需要临时变量
        // function getMaoPao(arr) {
        //        for(var i = 0; i < arr.length-1; i++) {
        //            for(var j = 0; j < arr.length - i -1; j++) {
        //              if(arr[j] < arr[ j + 1]) {
        //                var temp = arr [j]
        //                arr [j] = arr[j + 1]
        //                arr[j + 1] = temp
        //              }
        //            }
        //        }
        //        return arr
        // }
        // var re = getMaoPao([1,2,3,4,5,6,7,8,9,10,11,12,14,15,18,23,13,12,45,6,778,45,345])
        //    console.log(re);

        // 10.预解析案例 求 所有abc输出结果
        // f1()
        // console.log(c);
        // console.log(b);
        // console.log(a);
        // function f1() {
        //     var a = b = c = 9
        //     console.log(a);
        //     console.log(b);
        //     console.log(c);
        // }
        // 思路
        // (1)预解析过程 变量提升 函数提升
        // (2)注意：集体声明变量是需要逗号隔开,所以此处只声明了一个var a的变量
        // (3)根据作用域链 就近原则 局部变量a = 9
        // (4)虽然是在函数作用域里的但依然属于全局变量（因为没有var声明只赋值所以可以使用其值 结果为9
        // (5)因a是在函数域里局部声明的 外部从未有过声明 所以此全局作用域无法调用 结果is not defined 从未被调用
        // function f1() {
        //     var a;
        //     a = b = c = 9
        //     console.log(a);//9
        //     console.log(b);//9
        //     console.log(c);//9
        // }
        // f1()
        // console.log(c);//9
        // console.log(b);//9
        // console.log(a);//is not defined

        // 11.简易计算器
        // 选择5退出选项总是会先执行输入数字框 不直接退出计算器 所以我直接给了一个if条件 大于4的直接不执行计算器程序 也是被逼无奈 我知道肯定有更好的办法
        // for (var jsq = 1; jsq <= 5; jsq++) {
        //     jsq = (prompt('欢迎使用简易计算器：' + '\n' + '1.加法运算:' + '\n' + '2.减法运算:' + '\n' + '3.乘法运算:' + '\n' + '4.除法运算:' + '\n' + '5.退出:' + '\n' + '请输入您的选项:'))
        //     if (jsq <= 4) {//大于4的选项直接不执行代码 不就约等于做到了选项5的功能退出 - -
        //         var num1 = (prompt('请输入第一个数'))
        //         var num2 = (prompt('请输入第二个数'))
        //         switch (jsq) {
        //             case '1':
        //                 sum = 0
        //                 sum = parseFloat(num1) + parseFloat(num2)
        //                 alert(sum)
        //                 break
        //             case '2':
        //                 var re = 0
        //                 re = num1 - num2
        //                 alert(re)
        //                 break
        //             case '3':
        //                 re = 0
        //                 re = num1 * num2
        //                 alert(re)
        //                 break
        //             case '4':
        //                 re = 0
        //                 re = num1 / num2
        //                 alert(re)
        //                 break
        //         }
        //     } else {
        //         alert('正在退出')//用户选择5退出 if判断jsq > 4 则不执行if里语句 执行最终else语句即退出
        //     }
        // }

        // 1.数学内置对象 Math 无需声明 直接使用
        // 随机点名
        // function getRandom(max, min) {
        //     return Math.floor(Math.random() * (max - min + 1)) + min;//复制粘贴 知道怎么用的就行
        // //随机点名 需要return返回的这个函数式子
        // }
        // var arr = ['刘亦菲','张学友','刘德华','胡歌']
        // // 思路
        // // 数组的元素下标 用getRandom()函数生成的随机数代替 即达到 一刷新界面就生成 0~arr.length -1 这个范围之内的随机元素
        // console.log(arr[getRandom(0,arr.length-1)]);

        // 2.只有十次机会 猜1之50的数
        // 思路
        // 首先使用getRandom必须把这个函数式子（会随机生成输入的两个参数之间的数） 复制过来
        // 十次机会即需要循环十次 用户输入的内容 与判断条件
        // 用户答对了 就需要终止整个循环所以需要在 答对了执行语句下 加上 break代码 退出整个循环 
        // 如果用户十次机会全部用完未答对 即退出循环后友情提示 次数用完 （在循环外面添加代码）
        //  function getRandom(max, min) {
        //     return Math.floor(Math.random() * (max - min + 1)) + min//复制粘贴 知道怎么用的就行
        //  }
        // for(var i = 0;i < 10; i++) {
        //     var  num = prompt('请输入数')
        //    if(num > getRandom(1,50)) {
        //        alert('大了')
        //    } else if(num < getRandom(1,50) ) {
        //        alert('小了')
        //    }else {
        //        alert('答对了')
        //        break
        //    } 
        // }
        // alert('次数已用完')//当十次机会使用完（循环条件执行10次完毕后 在循环程序外面提醒用户次数用完）

        // 2.Date日期对象 属于构造函数 使用必须先new一下 才可以使用其方法（函数）
        // (1).写一个 2022年6月1号 星期三
        // var date = new Date()
        // var year = date.getFullYear()
        // // console.log(year);
        // var month = date.getMonth() + 1
        // // console.log(month);
        // var datel = date.getDate()
        // // console.log(datel);
        // var arr = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六']
        // var day = date.getDay()
        // // console.log(day);
        // console.log('今天是'+ year + '年'+ month + '月' + datel + '号 ' + arr[day]);

        //     函数封装
        //     写一个 2022年6月1号 星期三
        //     function time() {
        //     var date = new Date()// new Date()  变量名好像只能是date 注意
        //     var y = date.getFullYear()
        //     var m = date.getMonth() + 1
        //     var d = date.getDate()
        //     var day = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六']
        //    return('今天是' + y +'年'+ m  + '月' + d + '号 ' + day[date.getDay()]); //数组第几个元素（即今天是星期几）用getDay()自动生成 只要数组里面的元素顺序 不乱  那么getDay()就输出的结果就不用错 
        // }
        //   console.log(time()); 

        // // (2).封装一个函数 返回当前的时分秒  格式 08:08:08
        //   function times() {
        //       var date = new Date()
        //       var h = date.getHours()
        //       h = h < 10 ? '0' + h : h  
        //       var m = date.getMinutes()
        //       m = m < 10 ? '0' + m : m
        //       var s = date.getSeconds()
        //       s = s < 10 ? '0' + s : s
        //       return '为您报时' + h + ':' + m + ':' + s 
        //   }
        // var re = times()
        // console.log(re);

        // (3)倒计时
        // 总秒数换算天 时 分 秒的公式 知道会用就行了
        //  d = parseInt(总秒数/60/60/24)
        //  h = parseInt(总秒数/60/60%24)
        //  m = parseInt(总秒数/60%60)
        //  s = parseInt(总秒数%60)
        // 思路
        // 倒计时 需要用到总毫秒数 时间戳 因为时间戳不会有重复的数值
        // 拿变量（用户输入的总毫秒数） - 设置程序当前的总毫秒数 = 倒计时的总毫秒数
        // 倒计时总毫秒数 / 1000  = 总秒数 
        // 总秒数在套用上面的换算时分秒的公式即可
        //         function  daojishi(time) {
        //             var nowTime = +new Date()// 括号里没有参数时 输出的会是程序当前的总毫秒数
        //             var inputTime = +new Date(time)//括号里的参数为也可以自定义的 这里是实参传递来的
        //             var time = (inputTime - nowTime) / 1000
        //             var d = parseInt(time /60/60/24)
        //             d = d< 10? '0' + d : d 
        //             var h = parseInt(time /60/60%24)
        //             h = h <10 ? '0' + h : h
        //             var m = parseInt(time /60%60)
        //             m = m < 10 ? '0' + m : m
        //             var s = parseInt(time %60)
        //             s = s < 10 ? '0'+ s : s
        //             return d + ':' + h + ':' + m + ':' + s
        //         }
        //  console.log(daojishi('2022-6-7 14:00')); 
        // 倒计时重复练习
        // (2).封装一个函数 返回当前的时分秒  格式 08:08:08
        // function getTime() {
        //     var time = new Date()
        //     var h = time.getHours()
        //     h = h < 10 ? '0' + h : h //注意时间的格式 小于10时 需要在时分秒数字前补0 
        //     var m = time.getMinutes()
        //     m = m < 10 ? '0' + m : m
        //     var s = time.getSeconds()
        //     s = s < 10 ? '0' + s : s
        //     return h + ':' + m + ':' + s
        // }
        // console.log(getTime());
        //倒计时
        // 总秒数换算天 时 分 秒的公式 知道会用就行了
        //  d = parseInt(总秒数/60/60/24)
        //  h = parseInt(总秒数/60/60%24)
        //  m = parseInt(总秒数/60%60)
        //  s = parseInt(总秒数%60)
        // function countDown(time) {
        //     // 这里的+new Date()也是new了反正
        //     var nowTime = +new Date() //当前总毫秒数
        //     var inputTime = +new Date(time)//输入的总毫秒数
        //     var times = (inputTime - nowTime) / 1000 //输入总毫秒-当前总毫秒 = 总毫秒数
        //     var d = parseInt(times / 60 / 60 / 24)//天
        //     d = d < 10 ? '0' + d : d//小于10前面补0
        //     var h = parseInt(times / 60 / 60 % 24)//时
        //     h = h < 10 ? '0' + h : h
        //     var m = parseInt(times / 60 % 60)//分
        //     m = m < 10 ? '0' + m : m
        //     var s = parseInt(times % 60)//秒
        //     s = s < 10 ? '0' + s : s
        //     return d + '天' + h + '时' + m + '分' + s + '秒'
        // }
        // console.log(countDown('2022-6-3 17:00:00'));




        // Array 
        // 1.把高于2000的删除 [1500, 1200, 2000, 2100, 1800]
        // 添加与删除数组元素的方法 push()末尾添加属性的运用
        // 思路
        // (1)利用push添加属性 筛选元素 
        // (2)遍历旧数组把2000以下的值赛选出来通过push到新数组里
        // var arr = [1500, 1200, 2000, 2100, 1800]
        // var newArr = []
        // for (var i = 0; i < arr.length; i++) {
        //     if (arr[i] < 2000) {
        //         newArr.push(arr[i])
        //     }
        // }
        // console.log(newArr);


      
        // 2.数组索引去重 ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b']
        // 如果 新数组 索引 旧数组所有的元素 全等于 -1 则添加到新数组
        //    var arr = ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b']
        //    var newArr = []
        //    for(var i = 0; i< arr.length;i++) {
        //        if(newArr.indexOf(arr[i])=== -1) {
        //            newArr.push(arr[i])
        //        }
        //    }
        //    console.log(newArr);

        // 给定一个字符串 如：'abaasdffggghhjjkkgfddsssss3444343'问题如下
        // 1.字符串的长度
        // 数组才有长度 所以需要转为数组看length
        // 又因为没有分隔符直接是split转换数组结果会看成一个整体转换 所以不行
        // 最后考虑新声明一个空数组 push 字符串里的所有元素  charAt()通过位置返回字符
        // var str = 'abaasdffggghhjjkkgfddsssss3444343'
        //     var arr = []
        //    for(var i = 0; i < str.length;i++) {
        //        arr.push(str.charAt(i))
        //    }
        //    console.log(arr);//length：33



        // 3.查找字符串'abcoefoxyozzopp'中所有o出现的位置以及次数
        // indexOf()起始索引配合循环查找运用
        // 思路
        // (1)像这种查找元素 判断条件比较的复杂的 推荐使用while循环
        // (2)根据indexOf属性的特性 需要声明一个变量赋值为起始索引(第一个要查找的元素)
        // (3)因为要查很多次就需要循环 indexOf查找元素时如果不存在会返回-1的特性 （起始索引 !== -1） 就代表找到了 然后输出所有返回的索引（位置）
        // (4)要想继续往后查找 必须更改查找的起始位置 即掠过起始索引（起始索引 + 1） 就会继续后面的查找符合条件的o 并把每一次查找到（o）的结果保存到起始变量
        // 出现的总次数
        // (5)声明一个为0的新变量 在打印代码下加上 变量++ 递增即可（打印几次就会加几次 即 变量==总打印次数==总的出现次数）然后循环外输出即可
        // var str = 'abcoefoxyozzopp'
        // var oneo = str.indexOf('o')
        // var num = 0
        // while (oneo !== -1) {
        //     console.log(oneo);
        //     num++
        //     oneo = str.indexOf('o', oneo + 1)
        // }
        // console.log(num);

        // 老师做法
        // 通过数组索引方法indexOf属性 根据字符返回位置
        // 查找字符串'abcoefoxyozzopp'中所有o出现的位置以及次数
        // 先查找第一个o出现的位置
        // 然后 只要indexOf 返回的结果不是-1 就继续往后面查找
        // 因为indexOf() 只能查找第一个 所以后面的查找 一定是当前索引加1 从而继续查找
        //     var str = 'abcoefoxyozzopp'
        //     var index = str.indexOf('o')
        //     var num = 0
        //     while(index !== -1 ) {
        //         console.log(index);
        //         num++
        //         index = str.indexOf('o',index + 1)
        //     }
        // console.log(num);
        // 没啥好说的一模一样
        // 课后作业 求red的出现位置和次数 ['red','blue','red','green','pink','red']
        // 思路 
        // 先求出red第一次出现的位置
        //     var arr = ['red','blue','red','green','pink','red']
        //     var index = arr.indexOf('red')
        //     var num = 0
        //     while(index !== -1 ) {
        //         console.log(index);
        //         num++
        //         index = arr.indexOf('red',index + 1)
        //     }
        // console.log(num);

        // 字符串对象经典案例
        // 利用charAt()通过位置获取字符配合对象属性的调用 
        // 4.判断一个字符串 'abcoefoxyozzopp'中出现次数最多的字符 并统计次数
        // 核心算法 利用charAt()遍历这个字符串
        // 把每个字符都存储给对象，如果对象没有该属性 就为1 如果存在了就+1
        // 遍历对象 得到最大值和该字符
        // var str = 'abcoefoxyozzopp'
        // var o = {}
        // for (var i = 0; i < str.length; i++) {
        //     var chars = str.charAt(i)//最关键一步 把每一个字符都保存下来
        //     if (o[chars]) {
        //         o[chars]++// 直到循环到后面有了重复的 就让他自加1
        //     } else {
        //         o[chars] = 1//一开始o对象里肯定是都没有属性 所以都赋值1
        //     }
        // }
        // console.log(o);
        // // 遍历对象
        // var max = 0
        // var ch = ''
        // for (var k in o) {
        //     if (o[k] > max) {
        //         max = o[k]
        //         ch = k
        //     }
        // }
        // console.log('出现最多的字符是' + ch);
        // console.log('出现的总次数是' + max);

        // 5.有一个字符串 'abcoefoxyozzopp' 要求把所有的o替换为*
        //因为第一次循环就把第一个o换成了* 所以再次循环第二个o其实 就成为了第一个o 直至全部替换完 再也找不到o就返回-1   -1==-1就不会再执行循环了 
        // 把每次循环替换的*号保存起来 
        // var str1 = 'abcoefoxyozzopp'
        // while (str1.indexOf('o') !== -1) {
        //     str1 = str1.replace('o', '*') 
        // }
        // console.log(str1);




















    </script>
</head>

<body>

</body>

</html>